package uplb.ics.cs190.e2d.graphics;

import uplb.ics.cs190.e2d.lang.GameException;

/**
 * The <code>Color</code> class is used to encapsulate colors in the default
 * standard RGB color space. Every color has an implicit alpha value of 255
 * or an explicit one provided in the constructor. The alpha value defines the
 * transparency of a color. An alpha value of 255 means that the color is
 * completely opaque and an alpha value of 0 means that the color is completely
 * transparent.
 * <p>
 * This class is a minimal derivative of the AWT implementation in J2SE since
 * both J2ME and Android SDK do not contain the java.awt package.
 * <p>
 * The default constant color values are derived from the listings at the website
 * located in the URL http://www.cloford.com/resources/colours/500col.htm.
 * 
 * @author Acer
 *
 */
public class Color implements Transparency {

	/**
	 * The color black in the default standard RGB color space.
	 */
	public static final Color BLACK = new Color(0, 0, 0);
	
	/**
	 * The color white in the default standard RGB color space.
	 */
	public static final Color WHITE = new Color(255, 255, 255);
	
	/**
	 * The color red in the default standard RGB color space.
	 */
	public static final Color RED = new Color(255, 0, 0);
	
	/**
	 * The color green in the default standard RGB color space.
	 */
	public static final Color GREEN = new Color(0, 255, 0);
	
	/**
	 * The color blue in the default standard RGB color space.
	 */
	public static final Color BLUE = new Color(0, 0, 255);
	
	/**
	 * The color yellow in the default standard RGB color space.
	 */
	public static final Color YELLOW = new Color(255, 255, 0);
	
	/**
	 * The color gray in the default standard RGB color space.
	 */
	public static final Color GRAY = new Color(128, 128, 128);
	
	/**
	 * The color dark gray in the default standard RGB color space.
	 */
	public static final Color DARK_GRAY = new Color(64, 64, 64);
	
	/**
	 * The color light gray in the default standard RGB color space.
	 */
	public static final Color LIGHT_GRAY = new Color(192, 192, 192);
	
	/**
	 * The color magenta in the default standard RGB color space.
	 */
	public static final Color MAGENTA = new Color(255, 0, 255);
	
	/**
	 * The color cyan in the default standard RGB color space.
	 */
	public static final Color CYAN = new Color(0, 255, 255);
	
	/**
	 * The color brown in the default standard RGB color space.
	 */
	public static final Color BROWN = new Color(165, 42, 42);
	
	/**
	 * The color orange in the default standard RGB color space.
	 */
	public static final Color ORANGE = new Color(255, 165, 0);
	
	/**
	 * The color pink in the default standard RGB color space.
	 */
	public static final Color PINK = new Color(255, 192, 203);
	
	/**
	 * The color violet in the default standard RGB color space.
	 */
	public static final Color VIOLET = new Color(238, 130, 238);
	
	/**
	 * The red component of this <code>Color</code>.
	 */
	protected int r;
	
	/**
	 * The green component of this <code>Color</code>.
	 */
	protected int g;
	
	/**
	 * The blue component of this <code>Color</code>.
	 */
	protected int b;
	
	/**
	 * The alpha component of this <code>Color</code>.
	 */
	protected int alpha;
	
	/**
	 * Test the values of the RGB components and alpha. The RGB components
	 * and the alpha value must be equal to any number between 0 and 255.
	 * 
	 * @param r	the red component.
	 * @param g	the green component.
	 * @param b	the blue component.
	 * @param alpha	the alpha value.
	 * @throws GameException	the values of the RGB components or the alpha
	 * value is out of the normal range.
	 */
	private static void testColorValueRange(int r, int g, int b, int alpha) throws GameException {
		boolean rangeError = false;
		String badComponentString = "";
		
		if(alpha < 0 || alpha > 255) {
			rangeError = true;
			badComponentString += " Alpha";
		}
		if(r < 0 || r > 255) {
			rangeError = true;
			badComponentString += " Red";
		}
		if(g < 0 || g > 255) {
			rangeError = true;
			badComponentString += " Green";
		}
		if(b < 0 || b > 255) {
			rangeError = true;
			badComponentString += " Blue";
		}
		if(rangeError) {
			throw new GameException("Color parameter outside of expected range:"
					+ badComponentString);
		}
	}
	
	/**
	 * Creates a color with the specified RGB components and alpha value.
	 * 
	 * @param r	the red component.
	 * @param g	the green component.
	 * @param b	the blue component.
	 * @param alpha	the alpha value.
	 */
	public Color(int r, int g, int b, int alpha) {
		this.r = r;
		this.g = g;
		this.b = b;
		this.alpha = alpha;
		
		try {
			Color.testColorValueRange(r, g, b, alpha);
		} catch(GameException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Creates an opaque color with the specified RGB components.
	 * 
	 * @param r	the red component.
	 * @param g	the green component.
	 * @param b	the blue component.
	 */
	public Color(int r, int g, int b) {
		this(r, g, b, 255);
	}

	/**
	 * Gets the alpha value of this <code>Color</code>.
	 * 
	 * @return	the alpha value.
	 */
	public int getAlpha() {
		return this.alpha;
	}

	/**
	 * Gets the red component of this <code>Color</code>.
	 * 
	 * @return	the red component.
	 */
	public int getRed() {
		return this.r;
	}

	/**
	 * Gets the green component of this <code>Color</code>.
	 * 
	 * @return	the green component.
	 */
	public int getGreen() {
		return this.g;
	}

	/**
	 * Gets the blue component of this <code>Color</code>.
	 * 
	 * @return	the blue component.
	 */
	public int getBlue() {
		return this.b;
	}

	@Override
	public int getTransparency() {
		int alpha = getAlpha();
		int transparency = Transparency.TRANSLUCENT;
		
		if(alpha == 0xff) {
			transparency = Transparency.OPAQUE;
		} else if(alpha == 0) {
			transparency = Transparency.BITMASK;
		}
		
		return transparency;
	}
	
}